﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Access.PowerTools.Automation.Engine;
using Access.PowerTools.AbstractionLayer;
using Access.PowerTools.Utilities;

namespace Access.PowerTools.TestConsole
{
    [TestFixture]
    public class TestSet_0006_Automation
    {
        [SetUp]
        public void Setup()
        {
            Access.PowerTools.Settings.Globals.Init();
            //Access.PowerTools.Settings.Globals.SimulationModeOn = true;

            //Access.PowerTools.Settings.Globals.HostApplication =
            //    new Access.PowerTools.Simulation.Engine.SimulationCommunicationBridge();
        }

        [TearDown]
        public void TearDown()
        {
        }

        [Test]
        public void Test_001_ListAllObjects()
        {
            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();

            string dbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "Northwind.mdb";

            List<AccessDatabaseObjectInfo> list = bridge.GetObjectsInfo(dbFullPath);

            foreach (AccessDatabaseObjectInfo objectInfo in list)
            {
                Console.WriteLine("{0} - {1}", objectInfo.Type, objectInfo.Name);
            }
            Console.WriteLine(list.Count);

            bool ret = true;

            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }

        [Test]
        public void Test_002_StartAndQuitHostApplication()
        {
            bool ret = true;

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            IHostComunicationBridge iHost = null;

            string dbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "Northwind.mdb";

            try
            {
                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1}", iHost.ApplicationName, iHost.ApplicationVersion);

                bridge.QuitHostApplication();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = false;
            }

            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }

        [Test]
        public void Test_003_OpenCurrentDb()
        {
            bool ret = true;

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            IHostComunicationBridge iHost = null;

            string dbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "Northwind.mdb";

            try
            {
                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                bridge.OpenCurrentDatabase(dbFullPath);

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1}", iHost.ApplicationName, iHost.ApplicationVersion);

                bridge.QuitHostApplication();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = false;
            }

            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }

        [Test]
        public void Test_004_OpenCurrentDbListObjects()
        {
            bool ret = true;

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            IHostComunicationBridge iHost = null;

            string dbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "Northwind.mdb";

            try
            {
                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                bridge.OpenCurrentDatabase(dbFullPath);

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1}", iHost.ApplicationName, iHost.ApplicationVersion);

                List<AccessDatabaseObjectInfo> list = iHost.GetObjectsList();

                foreach (AccessDatabaseObjectInfo objectInfo in list)
                {
                    Console.WriteLine("{0} - {1}", objectInfo.Type, objectInfo.Name);
                }
                Console.WriteLine(list.Count);


                bridge.QuitHostApplication();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = false;
            }

            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }


        private void ReportProgressStatus(object sender, RunProgressEventArgs e)
        {
            Console.WriteLine ( string.Format("{0:HH:mm:ss.fff}: ", DateTime.Now) +
                          e.Message);

            //System.Threading.Thread.Sleep(10);
        }

        [Test]
        public void Test_005_OpenCurrentDbAndBackUp()
        {
            Console.WriteLine(DateTime.Now.ToString());
            Console.WriteLine("Starting backup test...");
            
            bool ret = true;

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            IHostComunicationBridge iHost = null;

            string dbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "Northwind.mdb";

            try
            {
                Console.WriteLine("Starting MS Access application...");
 
                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                Console.WriteLine("Opening currentdb '{0}'...", dbFullPath);
                bridge.OpenCurrentDatabase(dbFullPath);

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1} - '{2}'", 
                    iHost.ApplicationName, iHost.ApplicationVersion, iHost.CurrentDatabaseFullPath);

                List<AccessDatabaseObjectInfo> list = iHost.GetObjectsList();

                //foreach (AccessDatabaseObjectInfo objectInfo in list)
                //{
                //    Console.WriteLine("{0} - {1}", objectInfo.Type, objectInfo.Name);
                //}


                Console.WriteLine("Starting back-up...");
                Access.PowerTools.Settings.Globals.HostApplication =
                    bridge;
                
                AccessApplication application = new AccessApplication();

                Access.PowerTools.Database.BackUp.Plug_In.BackUpAgent
                    backup = new Access.PowerTools.Database.BackUp.Plug_In.BackUpAgent(application);

                string backUpFolder = Access.PowerTools.Settings.Globals.ExportFilesFolder;
                Access.PowerTools.Utilities.FilesAndFolders.ClearFolder(backUpFolder);

                backup.ReportProgressStatus += new EventHandler<RunProgressEventArgs>(ReportProgressStatus);    

                backup.BackUpDatabase(backUpFolder);
       
                Console.WriteLine("Back-up finished, exported {0} objects.", list.Count);

                Console.WriteLine("Exiting host application...");

                bridge.QuitHostApplication();

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = false;
            }
            finally 
            {
                if (bridge != null)
                    bridge.QuitHostApplication();
                bridge = null;

                Access.PowerTools.Settings.Globals.HostApplication = null;
                GC.Collect(); 
            }

            Console.WriteLine("Test DONE.");
            Console.WriteLine(DateTime.Now.ToString());

            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }


        [Test]
        public void Test_006_RestoreDbFromTestBackUp()
        {
            Console.WriteLine(DateTime.Now.ToString());
            Console.WriteLine("Starting restore test...");

            bool ret = true;

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            Access.PowerTools.Settings.Globals.HostApplication =
                bridge; 
            
            IHostComunicationBridge iHost = null;

            string seedDbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                 "nw.mdb";
            string restoreFolder = Access.PowerTools.Settings.Globals.RestoredFilesFolder;
            Access.PowerTools.Utilities.FilesAndFolders.ClearFolder(restoreFolder);     

            string dbFullPath = restoreFolder + "RESTORED_Northwind.mdb";

            try
            {
                Console.WriteLine("Copying test db to '{0}'...", dbFullPath);
                System.IO.File.Copy(seedDbFullPath, dbFullPath);

                Console.WriteLine("Starting MS Access application...");

                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                Access.PowerTools.Utilities.FilesAndFolders.BackUpFile(dbFullPath);
                Access.PowerTools.Utilities.FilesAndFolders.BackUpFile(dbFullPath);
                Access.PowerTools.Utilities.FilesAndFolders.BackUpFile(dbFullPath);

                Console.WriteLine("Opening currentdb '{0}'...", dbFullPath);
                bridge.OpenCurrentDatabase(dbFullPath);

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1}", iHost.ApplicationName, iHost.ApplicationVersion);

                Console.WriteLine("Starting restore...");
                Access.PowerTools.Settings.Globals.HostApplication =
                    bridge;

                AccessApplication application = new AccessApplication();

                Access.PowerTools.Database.Restore.Plug_In.RestoreAgent
                    backup = new Access.PowerTools.Database.Restore.Plug_In.RestoreAgent(application);

                string backUpFolder = Access.PowerTools.Settings.Globals.NorthdwindDatabaseSeedFilesFolder;

                backup.ReportProgressStatus += new EventHandler<RunProgressEventArgs>(ReportProgressStatus);

                backup.RestoreDatabase(backUpFolder);

                Console.WriteLine("Closing currentdb '{0}'...", dbFullPath);
                bridge.CloseCurrentDatabase();

                System.Threading.Thread.Sleep(500);   

                Console.WriteLine("Compacting current database...");
                bridge.CompactCurrentDatabase();

                System.Threading.Thread.Sleep(500);   

                //Console.WriteLine("Reopening currentdb '{0}'...", dbFullPath);
                //bridge.OpenCurrentDatabase(dbFullPath);

                Console.WriteLine("Listing current db objects...");
                List<AccessDatabaseObjectInfo> list = iHost.GetObjectsList();

                foreach (AccessDatabaseObjectInfo objectInfo in list)
                {
                    Console.WriteLine("{0} - {1}", objectInfo.Type, objectInfo.Name);
                }

                Console.WriteLine("Restore finished, imported {0} objects.", list.Count);

                Console.WriteLine("Exiting host application...");

                bridge.CloseCurrentDatabase();
                System.Threading.Thread.Sleep(500);   
 
                bridge.QuitHostApplication();

                bridge = null;

            }
            catch (Exception ex)
            {
                Console.WriteLine("Test_006_RestoreDbFromTestBackUp: " + ex.Message);
                Console.WriteLine("STACK TRACE");
                Console.WriteLine(ex.StackTrace);

                ret = false;
            }
            finally
            {
                if (bridge != null)
                      bridge.QuitHostApplication();
                bridge = null;

                Access.PowerTools.Settings.Globals.HostApplication = null;
                GC.Collect();
            }

            Console.WriteLine("Test DONE.");
            Console.WriteLine(DateTime.Now.ToString());

            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }


        [Test]
        public void Test_007_RestoreDbFromTestBackUp_IntoDbWithTables()
        {
            Console.WriteLine(DateTime.Now.ToString());
            Console.WriteLine("Starting restore test...");

            bool ret = true;

            AutomationCommunicationBridge bridge =
                new AutomationCommunicationBridge();
            Access.PowerTools.Settings.Globals.HostApplication =
                bridge;

            IHostComunicationBridge iHost = null;

            try
            {
                string seedDbFullPath = Access.PowerTools.Settings.Globals.SeedFilesFolder +
                                     "nw_withTables.mdb";
                string restoreFolder = Access.PowerTools.Settings.Globals.RestoredFilesFolder;
                Access.PowerTools.Utilities.FilesAndFolders.ClearFolder(restoreFolder);

                string dbFullPath = restoreFolder + "RESTORED_Northwind.mdb";

                
                Console.WriteLine("Copying test db to '{0}'...", dbFullPath);
                System.IO.File.Copy(seedDbFullPath, dbFullPath);

                Console.WriteLine("Starting MS Access application...");

                bridge.StartHostApplication();

                System.Threading.Thread.Sleep(1000);

                Console.WriteLine("Opening currentdb '{0}'...", dbFullPath);
                bridge.OpenCurrentDatabase(dbFullPath);

                System.Threading.Thread.Sleep(1000);

                iHost = bridge as IHostComunicationBridge;
                System.Console.WriteLine("{0} - {1}", iHost.ApplicationName, iHost.ApplicationVersion);

                Console.WriteLine("Starting restore...");
                Access.PowerTools.Settings.Globals.HostApplication =
                    bridge;

                AccessApplication application = new AccessApplication();

                Access.PowerTools.Database.Restore.Plug_In.RestoreAgent
                    backup = new Access.PowerTools.Database.Restore.Plug_In.RestoreAgent(application);

                string backUpFolder = Access.PowerTools.Settings.Globals.NorthdwindDatabaseSeedFilesFolder;

                backup.ReportProgressStatus += new EventHandler<RunProgressEventArgs>(ReportProgressStatus);

                backup.RestoreDatabase(backUpFolder);

                // it doesn't work yet - use close/reopen instead
                //Console.WriteLine("Compacting current database...");
                //bridge.CompactCurrentDatabase();

                Console.WriteLine("Closing currentdb '{0}'...", dbFullPath);
                bridge.CloseCurrentDatabase();

                Console.WriteLine("Reopening currentdb '{0}'...", dbFullPath);
                bridge.OpenCurrentDatabase(dbFullPath);

                Console.WriteLine("Listing current db objects...");
                List<AccessDatabaseObjectInfo> list = iHost.GetObjectsList();

                foreach (AccessDatabaseObjectInfo objectInfo in list)
                {
                    Console.WriteLine("{0} - {1}", objectInfo.Type, objectInfo.Name);
                }

                Console.WriteLine("Restore finished, imported {0} objects.", list.Count);

                Console.WriteLine("Exiting host application...");

                System.Threading.Thread.Sleep(500);   

                bridge.QuitHostApplication();

                bridge = null;

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                ret = false;
            }
            finally
            {
                if (bridge != null)
                    bridge.QuitHostApplication();
                bridge = null;

                Access.PowerTools.Settings.Globals.HostApplication = null;
                GC.Collect();
            }

            Console.WriteLine("Test DONE.");
            Console.WriteLine(DateTime.Now.ToString());

            Assert.IsTrue(ret, System.Reflection.MethodInfo.GetCurrentMethod().Name + "() Failed");
        }



    }
}
